<?php

namespace App\Http\Controllers\Admin\Content;

use App\Enums\ResponseEnum;
use App\Http\Controllers\AdminController;
use App\Models\Content\Article;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class ArticleController extends AdminController
{
    public function data(Request $request)
    {
        $model = $request->get('recycle') ? Article::onlyTrashed() : Article::query();
        if ($groupId = $request->get('groupId')) {
            $model->whereIn('id', function ($query) use ($groupId) {
                $query->select('id')->from('articles_has_category')->where('articles_has_category.category_id', $groupId);
            });
        }
        if ($keywords = $request->get('keywords')) {
            $model->where('title', 'like', $keywords.'%');
        }
        $total = $model->count();
        $page = (int)$request->get('page', 1);
        $pageSize = (int)$request->get('pageSize', 10);
        $list = $model->select(['id', 'sort', 'title', 'thumb', 'status', 'created_at', 'updated_at'])
            ->orderByDesc('id')->offset(($page-1)*$pageSize)->limit($pageSize)->get();
        return $this->succeed([
            'total' => $total,
            'rows'  => $list,
        ]);
    }

    public function store(Request $request)
    {
        $request->validate([
            'title' => ['required','max:120'],
            'redirect_url' => ['nullable','active_url'],
            'groupIds' => ['nullable','array'],
            'tags' => ['nullable','array']
        ]);
        $data = $request->only('sort', 'title', 'thumb', 'desc', 'redirect_url', 'content', 'status', 'is_top', 'groupIds', 'tags');
        DB::beginTransaction();
        try {
            $model = Article::query()->create([
                'sort' => (int)$data["sort"],
                'title' => $data["title"],
                'desc' => (string)$data["desc"],
                'thumb' => (string)$data["thumb"],
                'content' => htmlentities($data["content"]),
                'redirect_url' => (string)$data["redirect_url"],
                'status' => (int)$data["status"],
                'is_top' => (int)$data['is_top']
            ]);
            !empty($data['groupIds']) && $model->category()->attach($data['groupIds']);
            !empty($data['tags']) && $model->tags()->attach($data['groupIds']);
            $this->createSyslog('添加了一条文章记录', $data, $model);
            DB::commit();
            $item = $model->toArray();
            return $this->succeed([
                'id' => $item['id'],
                'created_at' => $item['created_at'],
                'updated_at' => $item['updated_at']
            ]);
        }catch (\Exception) {
            DB::rollBack();
        }
        return $this->fail();
    }

    public function show($id)
    {
        $item = Article::query()->with(['category' => function ($query) {
            $query->where('status', 1)->select('id', 'name');
        }, 'tags' => function ($query) {
            $query->where('status', 1)->select('id', 'name');
        }])->findOrFail($id);
        $data = $item->toArray();
        $data['groupIds'] = $item->category->pluck('id');
        $data['tags'] = $item->tags->pluck('id');
        if (!empty($data['content'])) {
            $data['content'] = htmlspecialchars_decode($data['content']);
        }
        return $this->succeed($data);
    }

    public function update($id, Request $request)
    {
        $request->validate([
            'title' => ['required','max:120'],
            'groupIds' => ['nullable','array'],
            'tags' => ['nullable','array'],
            'redirect_url' => ['nullable','active_url'],
        ]);
        $data = $request->only(['sort', 'title', 'thumb', 'desc', 'redirect_url', 'content', 'status', 'is_top', 'groupIds', 'tags']);
        $model = Article::query()->with(['category', 'tags'])->findOrFail($id);
        DB::transaction(function () use ($model, $data) {
            $model->update([
                'sort' => (int)$data["sort"],
                'title' => $data["title"],
                'desc' => (string)$data["desc"],
                'thumb' => (string)$data["thumb"],
                'content' => htmlentities($data["content"]),
                'redirect_url' => (string)$data["redirect_url"],
                'status' => (int)$data["status"],
                'is_top' => (int)$data['is_top']
            ]);
            $model->category->sync($data['groupIds']);
            $model->tags->sync($data['groupIds']);
            $this->createSyslog('更新了一条文章记录', $data, $model);
        });
        return $this->succeed();
    }

    public function destroy(Request $request)
    {
        $request->validate([
            'ids' => ['required','array','max:'.static::QUERY_LIMIT]
        ]);
        $ids = $request->get('ids');
        DB::transaction(function () use ($ids) {
            $rows = Article::query()->whereIn('id', $ids)->limit(static::QUERY_LIMIT)->delete();
            $this->createSyslog('批量删除了'.$rows.'条文章记录', ['ids' => implode(',', $ids)]);
        });
        return $this->succeed();
    }

    public function recover(Request $request)
    {
        $request->validate([
            'ids' => ['required','array','max:'.static::QUERY_LIMIT]
        ]);
        $ids = $request->get('ids');
        DB::transaction(function () use ($ids) {
            $rows = Article::onlyTrashed()->whereIn('id', $ids)->limit(static::QUERY_LIMIT)->restore();
            $this->createSyslog('批量恢复了'.$rows.'条文章记录', ['ids' => implode(',', $ids)]);
        });
        return $this->succeed();
    }

    public function expurgate(Request $request)
    {
        $request->validate([
            'ids' => ['required','array','max:'.static::QUERY_LIMIT]
        ]);
        $ids = $request->get('ids');
        $rows = Article::onlyTrashed()->select('id')->whereIn('id', $ids)->limit(static::QUERY_LIMIT)->withCount(['category', 'tags'])->get();
        abort_if(!$rows, ResponseEnum::DELETE_NOT_EXIST_ERROR);
        DB::transaction(function () use ($rows) {
            foreach ($rows as $row) {
                $row->category_count > 0 && $row->category()->detach();
                $row->tags_count > 0 && $row->tags()->detach();
                $row->forceDelete();
                $this->createSyslog('删除了一条文章记录', [], $row);
            }
        });
        return $this->succeed();
    }
}
